<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Hashes in Ruby</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Ruby, learn Ruby, hash, tutorial, programming language">
<meta name="description" content="In this part of the Ruby tutorial, we cover hashes.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>



<h1>Hashes in Ruby</h1>

<p>
This part of the Ruby tutorial will mention Ruby hashes. A hash is a collection
of key-value pairs. It is similar to an array. Unlike arrays, hashes can have
arbitrary objects as indexes. Arrays have can only have integers. Hashes
are sometimes called associated arrays. 
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<p>
Hashes are powerful collections. They have many methods that programmers
can use to do their work.
</p>


<h2>Hash creation</h2>

<p>
A hash can be created in two basic ways. Either
with the <code>new</code> keyword or by utilizing the hash literal.
</p>

<pre class="code">
#!/usr/bin/ruby

names = Hash.new
names[1] = "Jane"
names[2] = "Thomas"

puts names
</pre>

<p>
The first script creates a hash and adds two key-value pairs into the
hash object. 
</p>

<pre class="explanation">
names = Hash.new
</pre>

<p>
A hash object is created. 
</p>

<pre class="explanation">
names[1] = "Jane"
names[2] = "Thomas"
</pre>

<p>
We add two pairs of values to the hash. The 1, 2 numbers are the keys
to the hash. The keys are placed inside the square brackets. 
The names are the values that belong to the keys. 
</p>

<pre class="explanation">
puts names
</pre>

<p>
The <code>puts</code> method prints the string representation of the
hash to the console. It is also the string literal of the hash.
</p>

<pre>
$ ./create.rb
{1=>"Jane", 2=>"Thomas"}
</pre>

<p>
From the output we can see the literal representation of the names hash.
A hash is bouded by curly brackets. The keys and the values are paired 
with the => characters. 
</p>


<hr class="btm">

<p>
A <code>store</code> method can be used to initialize the hash with
some values. It can be use instead of the square brackets. 
</p>

<pre class="code">
#!/usr/bin/ruby

names = Hash.new
names.store(1, "Jane")
names.store(2, "Thomas")
names.store(3, "Rebecca")

puts names
</pre>

<p>
We have a similar script. This time we use the <code>store</code>
method. The method associates the given key with the given value 
and stores the pair in the hash. 
</p>

<pre class="explanation">
names.store(1, "Jane")
</pre>

<p>
The first parameter of the <code>store</code> method is the key and the 
second parameter is the value. 
</p>


<hr class="btm">

<p>
In the third script, we create a hash with the hash literal notation. 
The values are bound by the curly brackets. And the key-value pairs
are associated with the => characters. 
</p>

<pre class="code">
#!/usr/bin/ruby

domains = { "de" => "Germany",
            "sk" => "Slovakia",
            "hu" => "Hungary",
            "us" => "United States",
            "no" => "Norway"                       
          }

puts domains["de"]
puts domains["sk"]
</pre>

<p>
We create a domains hash with 5 pairs. This time both
keys and values are string types.
</p>

<pre class="explanation">
domains = { "de" => "Germany",
            "sk" => "Slovakia",
            "hu" => "Hungary",
            "us" => "United States",
            "no" => "Norway"                       
          }
</pre>

<p>
This is a hash literal notation. The key-value pairs are put
between the curly brackets. The items are separated by the comma
character. And the keys are associated with values using the 
=> characters combination. 
</p>

<pre class="explanation">
puts domains["de"]
</pre>

<p>
Here we print the domain value name associated with the "de" key. 
</p>

<pre>
$ ./create3.rb 
Germany
Slovakia
</pre>

<p>
Output of the code example. 
</p>


<h2>Basic work</h2>

<p>
In this section, we will present some methods for the very 
basic work with Ruby hashes. 
</p>

<pre class="code">
#!/usr/bin/ruby

names = Hash.new

names[1] = "Jane"
names[2] = "Thomas"
names[3] = "Robert"
names[4] = "Julia"
names[5] = "Rebecca"

puts "The size of the hash is #{names.size}"

puts names.keys.inspect
puts names.values.inspect
</pre>

<p>
In the above Ruby script, we create a hash with five values.
We introduce three hash methods. 
</p>

<pre class="explanation">
puts "The size of the hash is #{names.size}"
</pre>

<p>
The <code>size</code> method returns the size of the hash.
It is a synonym for the <code>length</code> method.
</p>

<pre class="explanation">
puts names.keys.inspect
puts names.values.inspect
</pre>

<p>
The <code>keys</code> method returns all keys of the hash. 
In a similar fashion, the <code>values</code> method returns
all the values of the hash. The returned data is in the form of 
an array. To have a more readable output, we also call the 
<code>inspect</code> method on the returned arrays. 
</p>

<pre>
$ ./basic.rb
The size of the hash is 5
[1, 2, 3, 4, 5]
["Jane", "Thomas", "Robert", "Julia", "Rebecca"]
</pre>

<p>
Ouput of the example. Note that the output of the last two methods
are two arrays. 
</p>


<hr class="btm">

<p>
The second example of the section presents three distinct hash methods.
</p>

<pre class="code">
#!/usr/bin/ruby

names1 = Hash.new

names1[1] = "Jane"
names1[2] = "Thomas"
names1[3] = "Robert"
names1[4] = "Julia"
names1[5] = "Rebecca"

names2 = names1.dup

puts names1.eql? names2

puts names1.empty?
names1.clear
puts names1.empty?
</pre>

<p>
The Ruby script creates a names hash. It calls three hash
methods on the object. 
</p>

<pre class="explanation">
names2 = names1.dup
</pre>

<p>
We create a duplicate of the hash by calling the <code>dup</code>
method. The method is inherited by the hash from the parent object.
</p>

<pre class="explanation">
puts names1.eql? names2
</pre>

<p>
The <code>eql?</code> method compares two hash objects. In our case
the hashes are equal and the line prints true.
</p>

<pre class="explanation">
puts names1.empty?
</pre>

<p>
The <code>empty?</code> method checks whether the hash is empty or not.
The line print false. Because the names1 hash has five items. 
</p>

<pre class="explanation">
names1.clear
puts names1.empty?
</pre>

<p>
The <code>clear</code> method deletes all items from the hash. The successive
call of the <code>empty?</code> method returns true. 
</p>

<pre>
$ ./basic2.rb
true
false
true
</pre>

<p>
Example output. 
</p>

<hr class="btm">

<p>
We have methods that can determine, whether a key or a value
is present in the hash. 
</p>

<pre class="code">
#!/usr/bin/ruby

domains = { :de => "Germany", :sk => "Slovakia",
            :no => "Norway", :us => "United States"
          }

puts domains.has_key? :de
puts domains.include? :no
puts domains.key? :me
puts domains.member? :sk

puts domains.has_value? "Slovakia"
puts domains.value? "Germany"
</pre>

<p>
We create a domains hash with four pairs. The keys are
symbols. Symbols are often used as keys, because they are more
efficient. 
</p>

<pre class="explanation">
puts domains.has_key? :de
puts domains.include? :no
puts domains.key? :me
puts domains.member? :sk
</pre>

<p>
Here we have four methods that determine, whether a key is in the hash.
They all do the same; they are synonyms. 
</p>

<pre class="explanation">
puts domains.has_value? "Slovakia"
puts domains.value? "Germany"
</pre>

<p>
These two methods check if the two strings are inside the hash. 
</p>


<pre>
$ ./has.rb
true
true
false
true
true
true
</pre>

<p>
This is the output of the example. 
</p>


<hr class="btm">

<p>
In the final example of the section, we will read values from the hash.
</p>

<pre class="code">
#!/usr/bin/ruby

stones = { 1 => "garnet", 2 => "topaz", 
           3 => "opal", 4 => "amethyst"
         }

puts stones.fetch 1
puts stones[2]
puts stones.values_at 1, 2, 3
</pre>

<p>
The Ruby script presents three hash methods for reading values of
a hash. 
</p>

<pre class="explanation">
puts stones.fetch 1
</pre>

<p>
The <code>fetch</code> method reads a value for a given key. 
</p>

<pre class="explanation">
puts stones[2]
</pre>

<p>
Square brackets can be used to get a value. In our case, the line
prints "topaz" to the console. 
</p>

<pre class="explanation">
puts stones.values_at 1, 2, 3
</pre>

<p>
The <code>values_at</code> method can be used to get multiple values
at one step. The method returns an array of the values for the given
keys. 
</p>

<pre>
$ ./read.rb
garnet
topaz
garnet
topaz
opal
</pre>

<p>
Output of the example. 
</p>


<h2>Looping through a hash</h2>

<p>
There are several methods that can be used to loop through a
Ruby hash. 
</p>

<pre class="code">
#!/usr/bin/ruby

stones = { 1 => "garnet", 2 => "topaz", 
           3 => "opal", 4 => "amethyst"
         }

stones.each { |k, v| puts "Key: #{k}, Value: #{v}" }
stones.each_key { |key| puts "#{key}" }
stones.each_value { |val| puts "#{val}" }
stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" }
</pre>

<p>
In the above example, we present four methods. We use them to 
display all keys, values and both keys and values of a hash. 
</p>


<pre class="explanation">
stones.each { |k, v| puts "Key: #{k}, Value: #{v}" }
</pre>

<p>
The <code>each</code> method calls the given block for each
key in the hash, passing key-value pair as parameter. 
</p>

<pre class="explanation">
stones.each_key { |key| puts "#{key}" }
</pre>

<p>
We use the <code>each_key</code> method to loop throug all
keys of a hash. They are printed to the console. 
</p>

<pre class="explanation">
stones.each_value { |val| puts "#{val}" }
</pre>

<p>
The <code>each_value</code> can be used to loop throug
the values of a hash. 
</p>

<pre class="explanation">
stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" }
</pre>

<p>
The <code>each_pair</code> method is a synonym for the 
<code>each</code> method. We loop through the keys and values
of the stones hash.
</p>

<pre>
$ ./loop.rb
Key: 1, Value: garnet
Key: 2, Value: topaz
Key: 3, Value: opal
Key: 4, Value: amethyst
1
2
3
4
garnet
topaz
opal
amethyst
Key: 1, Value: garnet
Key: 2, Value: topaz
Key: 3, Value: opal
Key: 4, Value: amethyst
</pre>

<p>
The output shows the keys and values, keys, values of
the stones hash. 
</p>


<h2>Deleting pairs</h2>

<p>
In the following examples, we will concern ourselves with methods
that delete pairs from the hashes. There are methods that delete
only a pair at a time and methods, that can delete multiple key-values
at one step. 
</p>

<pre class="code">
#!/usr/bin/ruby

names = Hash.new

names[1] = "Jane"
names[2] = "Thomas"
names[3] = "Robert"
names[4] = "Julia"
names[5] = "Rebecca"

names.delete 4
names.shift

puts names
</pre>

<p>
In the script we have two methods. The <code>delete</code> method
and the <code>shift</code> method. The <code>delete</code> method
removes and returns a value for a specified key. The <code>shift</code>
method deletes the first pair from the hash. It also returns the removed
pair as an array. 
</p>

<pre class="explanation">
names.delete 4
</pre>

<p>
Here we delete a pair 4 => "Julia". 
</p>

<pre class="explanation">
names.shift
</pre>

<p>
This code line removes the first pair, namely 1 => "Jane". 
</p>

<pre>
$ ./deleteitem.rb
{2=>"Thomas", 3=>"Robert", 5=>"Rebecca"}
</pre>

<p>
In the output we can see the pairs of the hash that are left. 
</p>

<hr class="btm">

<p>
The <code>reject</code> and the <code>delete_if</code> methods can
remove multiple pairs from a hash. The methods delete pairs that
return true for the given condition in the block. There is an important 
distinction between the two methods. The <code>reject</code> method
works on a copy of a hash while the <code>delete_if</code> works on
the original hash. 
</p>

<pre class="code">
#!/usr/local/bin/ruby

names1 = Hash.new

names1[1] = "Jane"
names1[2] = "Thomas"
names1[3] = "Robert"
names1[4] = "Julia"
names1[5] = "Rebecca"

puts names1.reject { |k, v| v =~ /R.*/ }
puts names1
puts names1.delete_if { |k, v| k&lt;=3 }
puts names1
</pre>

<p>
The example deletes multiple pairs using the previously mentioned
methods. 
</p>

<pre class="explanation">
puts names1.reject { |k, v| v =~ /R.*/ }
</pre>

<p>
The <code>reject</code> method removes all values that fit the
regular expression in the block. The modified hash is returned and
the original hash is not changed. 
</p>

<pre class="explanation">
puts names1
</pre>

<p>
The output of this line confirms, that the original hash was intact. 
</p>

<pre class="explanation">
puts names1.delete_if { |k, v| k&lt;=3 }
</pre>

<p>
In this case, we delete all pairs, for which the key is lower or
equal to 3. The method modifies the original hash. 
</p>

<pre>
$ ./massdelete.rb 
{1=>"Jane", 2=>"Thomas", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia", 5=>"Rebecca"}
{4=>"Julia", 5=>"Rebecca"}
{4=>"Julia", 5=>"Rebecca"}
</pre>

<p>
Output of the example. 
</p>


<h2>Adding hashes</h2>

<p>
Ruby has methods for hash addition. The <code>merge</code> 
and the <code>update</code> methods. 
</p>

<pre class="code">
#!/usr/bin/ruby

names1 = Hash.new

names1[1] = "Jane"
names1[2] = "Thomas"

names2 = Hash.new

names2[3] = "Robert"
names2[4] = "Julia"

names = names1.merge names2
puts names

names = names1.update names2
puts names
</pre>

<p>
In the Ruby script, we create two hashes. Then we apply 
<code>merge</code> and <code>update</code> methods on them. 
</p>

<pre class="explanation">
names = names1.merge names2
puts names
</pre>

<p>
We add two hashes, the names1 and the names2 and the result is 
assigned to the names hash. We print the newly created hash. 
</p>

<pre>
$ ./merge.rb
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
</pre>

<p>
As we can see, the final hashes contain pairs from the names1 and
names2 hashes. 
</p>

<h2>The merge vs merge!</h2>

<p>
In the final section, we recap a common ruby thing. Several methods have
their counterparts, that end with an explamation mark. The mark has
no syntactical meaning. It is a Ruby idiom. It hints a programmer, that
the method will actually modify an object, on which the method is called. 
</p>

<pre class="code">
#!/usr/bin/ruby

names1 = Hash.new

names1[1] = "Jane"
names1[2] = "Thomas"

names2 = Hash.new

names2[3] = "Robert"
names2[4] = "Julia"

names = names1.merge names2
puts names
puts names1

names = names1.merge! names2
puts names
puts names1
</pre>

<p>
We will demonstrate the difference on the <code>merge</code> 
and <code>merge!</code> methods. 
</p>

<pre class="explanation">
names = names1.merge names2
</pre>

<p>
The <code>merge</code> does not modify the names1 hash. It works
on its copy.
</p>

<pre class="explanation">
names = names1.merge! names2
</pre>

<p>
The <code>merge!</code> method works on the original hash. The names1
hash is changed. 
</p>


<pre>
$ ./merge2.rb
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
</pre>

<p>
Output.
</p>

<p>
In this chapter, we worked with Ruby hashes. 
</p>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified October 29, 2011 <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

